home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / dev / misc / ImageFXDevKit.lha / sdev / sas / examples / loaders / loadpbm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-03  |  7.2 KB  |  388 lines

  1. /*
  2.  * ImageFX Example Loader.
  3.  *
  4.  * Portable BitMap image loading routines.
  5.  *
  6.  * Currently supports PGM (GreyMap) and PPM (PixMap) images.
  7.  *
  8.  * NOTE:  Does NOT support comments in the files!
  9.  */
  10.  
  11. #include <exec/types.h>
  12. #include <exec/memory.h>
  13. #include <dos/dos.h>
  14. #include <clib/exec_protos.h>
  15. #include <clib/dos_protos.h>
  16. #include <stdio.h>
  17. #include <ctype.h>
  18. #include <string.h>
  19.  
  20. #include <scan/modall.h>
  21. #include <scan/loadsave.h>
  22.  
  23.  
  24. enum {
  25.    B_LoadPpm = 0,
  26.    B_LoadPgm,
  27.    TXT_COUNT
  28. };
  29.  
  30. #define BUFLEN      (65536L)
  31.  
  32. static BPTR          handle;
  33. static UBYTE        *buffer;
  34. static ULONG         index;
  35. static ULONG         count;
  36. static short         unchar;
  37.  
  38.  
  39. /*
  40.  * PBM_Open() - Open a file for buffered reading.
  41.  */
  42.  
  43. static
  44. BOOL PBM_Open (char *fname)
  45. {
  46.    SetError(0);
  47.  
  48.    buffer = AllocMem(BUFLEN, MEMF_PUBLIC|MEMF_CLEAR);
  49.    if (buffer == NULL) ReturnError(ERR_Memory, FALSE);
  50.  
  51.    handle = Open(fname, MODE_OLDFILE);
  52.    if (handle == NULL) {
  53.       FreeMem(buffer, BUFLEN);
  54.       ReturnError(ERR_Open, FALSE);
  55.    }
  56.  
  57.    index = BUFLEN;
  58.    count = 0;
  59.    unchar = -1;
  60. }
  61.  
  62. /*
  63.  * PBM_Close() - Close a buffered file.
  64.  */
  65.  
  66. static
  67. void PBM_Close (void)
  68. {
  69.    Close (handle);
  70.    FreeMem(buffer, BUFLEN);
  71. }
  72.  
  73. /*
  74.  * PBM_Getc() - Read next character from the buffered file.
  75.  */
  76.  
  77. static
  78. short PBM_Getc (void)
  79. {
  80.    UBYTE c;
  81.  
  82.    if (unchar != -1) {
  83.       c = unchar;
  84.       unchar = -1;
  85.    }
  86.    else {
  87.       if (!count) {
  88.          count = Read (handle, buffer, BUFLEN);
  89.          if (count < 1) return(-1);
  90.          index = 0;
  91.       }
  92.       c = buffer[index++];
  93.       count--;
  94.    }
  95.    return ((short)c);
  96. }
  97.  
  98. /*
  99.  * PBM_Ungetc() - Push back last character read.
  100.  */
  101.  
  102. static
  103. void PBM_Ungetc (UBYTE c)
  104. {
  105.    unchar = c;
  106. }
  107.  
  108. /*
  109.  * PBM_Getw() - Read next white-space bounded word from the
  110.  *               buffered file.
  111.  */
  112.  
  113. static
  114. BOOL PBM_Getw (char *buf, int max)
  115. {
  116.    int i = 0;
  117.    short c;
  118.  
  119.    do {
  120.       c = PBM_Getc();
  121.       if (c < 0) return(FALSE);
  122.    }
  123.    while (isspace(c));
  124.  
  125.    buf[i++] = c;
  126.    while (i < max - 1) {
  127.       c = PBM_Getc();
  128.       if (c < 0) break;
  129.       if (isspace(c)) break;
  130.       buf[i++] = c;
  131.    }
  132.    buf[i] = '\0';
  133.  
  134.    return(TRUE);
  135. }
  136.  
  137.  
  138.  
  139. /*
  140.  * LoadPGM() - Load a PGM (Portable GreyMap) file.
  141.  */
  142.  
  143. struct Buffer *LoadPGM (char *fname)
  144. {
  145.    struct Buffer *buffer;
  146.    char buf[16];
  147.    int wid, ht, val;
  148.    short i, j;
  149.    UBYTE *grey;
  150.    BOOL text;
  151.  
  152.    SetError(0);
  153.  
  154.    if (!PBM_Open(fname)) {
  155.       return(NULL);
  156.    }
  157.  
  158.    PBM_Getw (buf, 16);
  159.    if (strcmp("P2",buf) && strcmp("P5",buf)) {
  160.       PBM_Close();
  161.       return(NULL);
  162.    }
  163.    text = (buf[1] == '2');
  164.  
  165.    PBM_Getw (buf, 16);
  166.    sscanf (buf, "%d", &wid);
  167.    PBM_Getw (buf, 16);
  168.    sscanf (buf, "%d", &ht);
  169.    PBM_Getw (buf, 16);
  170.  
  171.    buffer = AllocBuffer (NULL, wid, ht, 1, 8, 0);
  172.    if (buffer == NULL) {
  173.       PBM_Close();
  174.       return(NULL);
  175.    }
  176.  
  177.    strcpy (buffer->Type, "PGM");
  178.    strcpy (buffer->Name, fname);
  179.  
  180.    ShowStatus(buffer);
  181.  
  182.    BeginBar(GetStr(B_LoadPgm, "Load PGM"), ht, TRUE);
  183.    for (j = 0; j < ht; j++) {
  184.       if (Bar(j)) {
  185.          KillBuffer(buffer);
  186.          buffer = NULL;
  187.          SetError(ERR_UserCancel);
  188.          break;
  189.       }
  190.       GetBufLine (buffer, &grey, NULL, NULL, j);
  191.       for (i = 0; i < wid; i++) {
  192.          if (text) {
  193.             PBM_Getw(buf,16);
  194.             sscanf (buf, "%d", &val);
  195.             *grey++ = (UBYTE)val;
  196.          }
  197.          else {
  198.             *grey++ = PBM_Getc();
  199.          }
  200.       }
  201.    }
  202.    EndBar(NULL);
  203.  
  204.    PBM_Close();
  205.  
  206.    buffer->OriginalDepth = 8;
  207.  
  208.    return(buffer);
  209. }
  210.  
  211. /*
  212.  * LoadPPM() - Load a PPM (Portable PixMap) file.
  213.  */
  214.  
  215. struct Buffer *LoadPPM (char *fname)
  216. {
  217.    struct Buffer *buffer;
  218.    char buf[16];
  219.    int wid, ht, val;
  220.    short i, j;
  221.    UBYTE *red, *grn, *blu;
  222.    BOOL text;
  223.  
  224.    SetError(0);
  225.  
  226.    if (!PBM_Open(fname)) {
  227.       return(NULL);
  228.    }
  229.  
  230.    PBM_Getw (buf, 16);
  231.    if (strcmp("P3",buf) && strcmp("P6",buf)) {
  232.       PBM_Close();
  233.       return(NULL);
  234.    }
  235.    text = (buf[1] == '3');
  236.  
  237.    PBM_Getw (buf, 16);
  238.    sscanf (buf, "%d", &wid);
  239.    PBM_Getw (buf, 16);
  240.    sscanf (buf, "%d", &ht);
  241.    PBM_Getw (buf, 16);
  242.  
  243.    buffer = AllocBuffer (NULL, wid, ht, 3, 8, 0);
  244.    if (buffer == NULL) {
  245.       PBM_Close();
  246.       return(NULL);
  247.    }
  248.  
  249.    strcpy (buffer->Type, "PPM");
  250.    strcpy (buffer->Name, fname);
  251.  
  252.    ShowStatus(buffer);
  253.  
  254.    BeginBar(GetStr(B_LoadPpm, "Load PPM"), ht, TRUE);
  255.    for (j = 0; j < ht; j++) {
  256.       if (Bar(j)) {
  257.          KillBuffer(buffer);
  258.          buffer = NULL;
  259.          SetError(ERR_UserCancel);
  260.          break;
  261.       }
  262.       GetBufLine (buffer, &red, &grn, &blu, j);
  263.       for (i = 0; i < wid; i++) {
  264.          if (text) {
  265.             PBM_Getw(buf,16);
  266.             sscanf (buf, "%d", &val);
  267.             *red++ = (UBYTE)val;
  268.             PBM_Getw(buf,16);
  269.             sscanf (buf, "%d", &val);
  270.             *grn++ = (UBYTE)val;
  271.             PBM_Getw(buf,16);
  272.             sscanf (buf, "%d", &val);
  273.             *blu++ = (UBYTE)val;
  274.          }
  275.          else {
  276.             *red++ = PBM_Getc();
  277.             *grn++ = PBM_Getc();
  278.             *blu++ = PBM_Getc();
  279.          }
  280.       }
  281.    }
  282.    EndBar(NULL);
  283.  
  284.    PBM_Close();
  285.  
  286.    buffer->OriginalDepth = 24;
  287.  
  288.    return(buffer);
  289. }
  290.  
  291.  
  292. /*
  293.  * LM_Load() - Read the given file; we check the ID to see whether
  294.  *             it is color or grey and call the right load function.
  295.  *
  296.  */
  297. struct Buffer * __saveds __asm LM_Load (register __a0 char *fname,
  298.                                         register __d0 int id,
  299.                                         register __a1 LONG *args)
  300. {
  301.    if (id == 0)
  302.       return (LoadPPM(fname));
  303.    else
  304.       return (LoadPGM(fname));
  305. }
  306.  
  307.  
  308. /*
  309.  * LM_LoadPalette() - Load a palette from the given file.  We don't
  310.  *                    support this, so we just return an error.
  311.  *
  312.  */
  313. BOOL __saveds __asm LM_LoadPalette (register __a0 char *fname,
  314.                                     register __a1 struct Palette *pal,
  315.                                     register __d0 int id)
  316. {
  317.    ReturnError(ERR_NoPalette, FALSE);
  318. }
  319.  
  320. /*
  321.  * Table of formats we support.
  322.  */
  323. static
  324. struct LoadFormat loadformats[] = {
  325.    { "P3", 2, "PPM (Text)", 0 },   /* color */
  326.    { "P6", 2, "PPM (Binary)", 0 },
  327.    { "P2", 2, "PGM (Text)", 1 },   /* grey */
  328.    { "P5", 2, "PGM (Binary)", 1 },
  329.    { NULL }
  330. };
  331.  
  332. /*
  333.  * LM_Signatures() - Return the table of signature bytes we
  334.  *                   recognize.
  335.  */
  336. struct LoadFormat * __saveds LM_Signatures (void)
  337. {
  338.    return (loadformats);
  339. }
  340.  
  341. /*
  342.  * LM_CheckFile() - Not needed for this loader.
  343.  *
  344.  */
  345. BOOL __saveds __asm LM_CheckFile (register __a0 char *fname)
  346. {
  347.    return(FALSE);
  348. }
  349.  
  350.  
  351. /**********************************************************************\
  352.  
  353.                Library Functions and Initialization Stuff
  354.  
  355. \**********************************************************************/
  356.  
  357. ULONG FuncTable[] = {
  358.    /* These four MUST be present */
  359.    (ULONG) LibOpen,
  360.    (ULONG) LibClose,
  361.    (ULONG) LibExpunge,
  362.    (ULONG) LibNull,
  363.  
  364.    (ULONG) LM_Load,
  365.    (ULONG) LM_LoadPalette,
  366.    (ULONG) LM_Signatures,
  367.    (ULONG) LM_CheckFile,
  368.  
  369.    /* End with -1L */
  370.    (ULONG) -1L
  371. };
  372.  
  373. UBYTE LibraryID[]    = "$VER: PBM Loader 1.00.05 (29.9.92)";
  374. UBYTE LibraryType    = NT_LOADER;
  375.  
  376. LONG __saveds __stdargs UserOpen (struct ModuleBase *modbase)
  377. {
  378.    modbase->Language = "Loader_PBM";
  379.    modbase->LangCount = TXT_COUNT;
  380.    return(TRUE);
  381. }
  382.  
  383. LONG __saveds __stdargs UserClose (struct ModuleBase *modbase)
  384. {
  385.    return(TRUE);
  386. }
  387.  
  388.